/*************************************************************************
*		Copyright (c) 1989,1990 Stone Design Corp.  All rights reserved. 
*		"Do what you will, you will anyway...."-- andrew stone 4-29-90
***************************************************************************/

//			SliderDualActing:Slider:Control:View:Responder:Object

#import "SliderDualActing.h"
#import "SliderCellFine.h"

/********************************************************
	 
 //  initialization routines called by clients:

 //  This allows dual messages to be sent:
- setUpTarget:anObject action:(SEL)anAction;
- setUpTarget:anObject action:(SEL)anAction isContinuous:(BOOL)flag;

 // This lets you configure how hi and lo the slider can go.
- setMax:(double)max allowHigher:(BOOL)hi min:(double)min allowLower:(BOOL)lo;

 // call this after you have set the max and min: it sets your start value:
- setAltStep:(double)step whole:(BOOL)flag default:(double)value;

 // Set the textFields's doubleing format this way:
- setFormat:(BOOL)flag left:(int)l right:(int)r;

 // set your undo target with:
- setUndoTarget:target position:(int)pos;

 // Example :
 // (Works best after appDidInit message, textPal is guaranteed to exist):
     
    [[[[dualSlider setUpTarget:self action:@selector(display)]
    		setMax:360. allowHigher:NO min:-360. allowLower:NO]
    		setAltStep:1. whole:YES default:0]
			setFormat:NO left:1 right:3]; 

 // If the client object wants to handle undo [by default SliderDA does]:

    [anObject setUndoTarget:(id)target  tag:(int)clientTag];
    
    example:
    [anObject setUndoTarget:textArtView  tag:GRAY_POS];

********************************************************/

@implementation SliderDualActing

+ initialize	// who we are and where we stand in the struggle
{
    [SliderDualActing setCellClass:[SliderCellFine class]];
	return self;
}

+ newFrame:(const NXRect *)frameRect
{
   self = [super newFrame:frameRect];
   undoTarget = self;					// override this if needed
   return self;
}

 // IB sender methods:

- sendTextAction:sender     /// method for textField
{
    [undoTarget setLastThing:undoPosition];   // param not used
	[self setFloatValue:[sender floatValue]];
	[self sendAction:upAction to:upTarget];
	return self;
}
- incrementDecrement:sender	// method for buttons [let tag=position in IB]
{
	id retVal;
	[self _sendSetLastThing];         ///Mon Nov 20 20:37:19 MST 1989 Undo
	retVal =  [sender selectedTag]==0? [cell decrement]: [cell increment];	
	[self display];
	return retVal?[self sendAction:upAction to:upTarget]:nil;
}
  

 // overridden superclass methods:

- mouseDown:(NXEvent *)e
{
    // here we must trap oldvalue!!
    [undoTarget setLastThing:undoPosition];   // param not used
    [super mouseDown:e];
	[self sendAction:upAction to:upTarget];	// send our up/text  method
    return self;
}
- setFloatValue:(float)aFloat
{
	double val = [cell checkValue:aFloat];
	[cell setFloatValue:val];
	[textPal setFloatValue:val];
	[self display];
	return self;
}
- setIntValue:(int)anInt
{
	double val = [cell checkValue:(double)anInt];
	[cell setFloatValue:val];
	[textPal setFloatValue:val];
	[self display];
	return self;
}

// initialization routines called by clients:
- setUpTarget:anObject action:(SEL)anAction
{
    upTarget = anObject;
    upAction = anAction;
	[cell _setAlwaysSendUpAction:NO];
	return self;
}
- setUpTarget:anObject action:(SEL)anAction isContinuous:(BOOL)flag
{
    upTarget = anObject;
    upAction = anAction;
	[cell _setAlwaysSendUpAction:flag];
	return self;
}
	
- setMax:(double)max allowHigher:(BOOL)hi min:(double)min allowLower:(BOOL)lo
{
	[cell setMax:max allowHigher:hi min:min allowLower:lo];
	return self;
}

- setAltStep:(double)step whole:(BOOL)flag default:(double) val
{
	lastValue = val; [self setFloatValue:val];              // init values
	[cell setAltStep:step whole:flag default:val];   // pass it to cell
	return self;
}

- setFormat:(BOOL)flag left:(unsigned)l right:(unsigned)r
{
	[textPal setFloatingPointFormat:flag left:l right:r];
	return self;
}


 // Historic ones:  

- setDefault:(double) def
{
	[cell setDefault:def];
	return self;
}
- setUpTarget:anObject
{
    upTarget = anObject;
	return self;
}
- setUpAction:(SEL)anAction
{
    upAction = anAction;
   	return self;
}

 // archive methods:   // not tested C.E.
- read:(NXTypedStream *)stream
{
	[super read:stream];
	NXReadTypes(stream, "@@@ii", &textPal,&upTarget,&undoTarget,
								&upAction,&undoPosition);
	[cell setTextPal:textPal];
	return self;
}

- write:(NXTypedStream *)stream
{
	[super write:stream];
	NXWriteTypes(stream, "@@@ii", &textPal,&upTarget,&undoTarget,
								&upAction,&undoPosition);
	[cell setTextPal:textPal];
	return self;
}

/// UNDO methods

- setUndoTarget:targ tag:(int)pos
{
   undoTarget = targ;
   undoPosition = pos;
   return self;
}

- setLastThing:(int)thing
{  
 // uncomment next line if you implement an undo object
 //  [[NXApp undoObj] setLastClass:self];  // We cache the old value.
   lastValue =  [cell floatValue];
   return self;
}

- undo
{
   float temp = [cell floatValue];
   [self setFloatValue:lastValue];
   lastValue=temp;
   // Here you may want to have some visual updating of a view:
   // [[NXApp mainWindow] display]; 
   return self;
}

- _sendSetLastThing
{
   return [undoTarget setLastThing:undoPosition];
}
- _sendIt		// called by cell to continously send up message
{
	return  [self sendAction:upAction to:upTarget];
}

 // Misc and private:
 
-(BOOL)isDecimal
{ 
  return [cell isDecimal];
}

- textPal
{
  return textPal;
}
- setTextPal:anObject
{
  textPal = anObject;
  [cell setTextPal:textPal];		// let cell cache it as well
  return self;
}

@end

